home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib25 / mntlib25.zoo / _udivmod.s < prev    next >
Text File  |  1992-12-12  |  2KB  |  78 lines

  1. | unsigned long division and modulus routines
  2. |
  3. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  4. |
  5. |
  6. | Revision 1.1, kub 03-90
  7. | first version, replaces the appropriate routine from fixnum.s.
  8. | Should be faster in more common cases. Division is done by 68000 divu
  9. | operations if divisor is only 16 bits wide. Otherwise the normal division
  10. | algorithm as described in various papers takes place. The division routine
  11. | delivers the quotient in d0 and the remainder in d1, thus the implementation
  12. | of the modulo operation is trivial.
  13.  
  14.     .text
  15.     .even
  16.     .globl    __udivsi3, ___udivsi3, .uldiv
  17.     .globl    __umodsi3, ___umodsi3, .ulrem
  18.  
  19. .uldiv:
  20. __udivsi3:
  21. ___udivsi3:
  22.     movel    d2,a0        | save registers
  23.     movel    d3,a1
  24.     clrl    d0        | prepare result
  25.     movel    sp@(8),d2    | get divisor
  26.     beq    9f        | divisor = 0 causes a division trap
  27.     movel    sp@(4),d1    | get dividend
  28. |== case 1) divident < divisor
  29.     cmpl    d2,d1        | is divident smaller then divisor ?
  30.     bcs    8f        | yes, return immediately
  31. |== case 2) divisor has <= 16 significant bits
  32.     tstw    sp@(8)
  33.     bne    2f        | divisor has only 16 bits
  34.     movew    d1,d3        | save dividend
  35.     clrw    d1        | divide dvd.h by dvs
  36.     swap    d1
  37.     beq    0f        | (no division necessary if dividend zero)
  38.     divu    d2,d1
  39. 0:    movew    d1,d0        | save quotient.h
  40.     swap    d0
  41.     movew    d3,d1        | (d1.h = remainder of prev divu)
  42.     divu    d2,d1        | divide dvd.l by dvs
  43.     movew    d1,d0        | save quotient.l
  44.     clrw    d1        | get remainder
  45.     swap    d1
  46.     bra    8f        | and return
  47. |== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)
  48. 2:
  49.     moveq    #31,d3        | loop count
  50. 3:
  51.     addl    d1,d1        | shift divident ...
  52.     addxl    d0,d0        |  ... into d0
  53.     cmpl    d2,d0        | compare with divisor
  54.     bcs    0f
  55.     subl    d2,d0        | big enough, subtract
  56.     addw    #1,d1        | and note bit in result
  57. 0:
  58.     dbra    d3,3b
  59.     exg    d0,d1        | put quotient and remainder in their registers
  60. 8:
  61.     movel    a1,d3
  62.     movel    a0,d2
  63.     rts
  64. 9:
  65.     divu    d2,d1        | cause division trap
  66.     bra    8b        | back to user
  67.  
  68.  
  69. .ulrem:
  70. __umodsi3:
  71. ___umodsi3:
  72.     movel    sp@(8),sp@-    | push divisor
  73.     movel    sp@(8),sp@-    | push dividend
  74.     jbsr    __udivsi3
  75.     addql    #8,sp
  76.     movel    d1,d0        | return the remainder in d0
  77.     rts
  78.